1000101111010101011101010110010101111100001011110111110111101000010011010001111000111111101010110000010100011100101100010100110101010101010110111000011011001111001011111000100000111010010111101100100101100010000111111100100101011001110110001110111100111101111010010111111100101100100111000101001110010101000011110011011110101010001010100010101101110001111001010011011111011011101111111001100110011101 1010000010110011110010010101011000100001100110101111001011011001011110100011101110011001110010101101110100110010000101000000000000011001101111111000101000000010011111001010011011101101111010101011100010110000000100000110001100010011000001010011010011110100001011110001011111011011110100100100011011111011100100011110010100101100100111010100010111100110110011101111110010110101111111010100100110010011 0111100111100010100100000011111110010111011011001001110000111000010110111000100101101010000000010000101011000001011001001110010111011110000110100011101011110110110100011110011110110111010000000111000011101101010110010100110011100110001000001010000001110101011001010000011011011011111011101111001100101100111011100110000101000011100010000011000110100100100010010111110111011000011100101001101111110111 0011100111010100011011011001011000011001010011101010010101010000111110010110111000100000111010001110101111000100001000101100101000100111010011010101101000101001000101101100011000111001010010011010110011111100000111010101001001001011000010110010101000110000011100000111000011001010101110111101100010110000001001101001001000010101100100100001111100111101110100011011000100111111110100001001110011010100 0100010000100011010000111100010110000111110111011001001011010110011010100100110010110110010011011001011101000000000100001111100010111001000100010001010100010101111011010010011011101011011011011001111000101110000010110000001101011011001100001100111000001101111100100001010101010010111101010101110000001011110011011010100111100111100010110010111100111110001010010000011010101111011110001110010000001000 0101011101011001110010101010011000001001111011100000100101101010100011010101110100101110110111110010011001000000100110110011100110111111001011001101111100100111110111111101110111101101111110001101001010100011101010001001101101010111100010000010101000100000011110101110101001001111110110001001011000111001100010100100100110111001100001110110000000010000000000110101101010001010101110010100100000101001 1011011101110110011100101000010011000100000110111010101000101100011100001110000110110100010110100100010010000111110000111000011011111010100100000100010101001010010110110101001011101001111110110001100000110111111011100110101110010001100101000000011001000101100101101111110101010100101000011110111100111011111000111100010010110000011101000000111001100000000010000111110100110001000011101000111000111101 1011111110100111110011010011001000010100011011101001100010001000111010010011010101011000001001111011111001000010010000110001000001001011111110000111110100001111101110000111001001011101000111101100111101110101101011001100001101000101000011000011110110000101111000001100100101011110101111111110111001010001110101011110100001010001111011000011111100001101010010010100000001110111110101111101000010110101 0111100111111111111010010001100110100011101010110010100100101101111000100101100110010010000000111000111111101000110110111000010111000111010001010110010010101101001000111011111011100110111100011011100011110110010001001111010001001000111010101100000010010000111010100101010001101001000001010100101000111110000100011011011010110111111001110101110011100010011010101100011110001111111110010011101101100111 1001011110000011111011011100101101111001111011001011011100010110111111001001101100101011111110010010010000110000011000001100000010000101011000011100110101001001011011000101010001001011101110001101101111100000000111000101010010101111111011110000101011000100010111100001100110110000100111101110101101001000100110100100000100001001000010110000100001001000111101101100001101111110010101010000011101000111 1111101110011011111100000100000100001000010111011110110101010110100100110011010110011011000011111000101010010011000111101010011000101101011111010110100010000110001001110110000010101001110101101101110101001011000001000101111010000001111011000110000101010101111000011101011011011110110011111111000111001010001000100100101000110010100000111000100000100000100001111110101100100011001110101000011011000010 1111010100010101100000101101111011011000111000010001110110100001101000100101001111101111111000111000011110000001001101001011000111110101000111000110110011000011101101011011000001010000110000001101011110110011110110110110111111001101110010101011011011000000001101000010111101100011101100100011110010001001100111001100000101110011001011001010100110001011100010000011100001011110011100110111000001110000 1011000011011001010000000110100101101110100000100011010010101011010011110001010110001100110101011010011010011010101101001010100111111111110101101111110111011001010110001010110110011000110111111000100011101001010100011010010111001011010111110111100110011000110100101001110000010100110100000000011010110001100010101000010011001011111001101010010011100100001111111001110000000111010111111100111111000110 1011110011001100000000001111111011000001001111100110011110001011011011101001011000000101100011000100110101111000010111000110000111000001111101011011110101101110101011110100101101010010101101011100000011101100101110001001100110000111011010111011011010010101110100110101101011010110111001100000000111110001001110100111000111100101010000011111111110110101100000010111100100100011000010011000000010000101 0110101010100111110101001101010100110100000011001001101010000110110110000111001101000111010111110010011001000110000110110111110011010000010011111010011111100011001110011001111010010100000010111010011110101011000000001001100100001000010010010011100011100110001100110001000111101011100011100000010111001000001001111011010100011111111010100000001110001001100111110011011110101100100000000011011010001111 1001111011111110101111110110101001000001101001000101010010100001111110111111100011000010110000111001001001001111101001010100010100110011110100000100111010000100010111000100010001101101000001110000001000000010011111011100011110100111100111111100100111101001001011111011111111100001100110000101001001100011110011111010001010101101000011010110111010110110000110001100000011101001011111010010000011100100 1011011101000111010101010110000000100001010001110000010100010101101001010110011000010111010110000111110110100011111010000110000001111111101011111001010111100001000100000011111100110110011100110011111100000001001001000111000000010110111000110101110100000111101000111101110100000011101000111011110001111000000100111000111111010011101010011101101011101101100100111000110001100011111010110101000101101000 0000000001101110000000000011100011111101100011001000111011000110011110010111010001000011011001011100100100111110111111100000001011011111001101001100000001111001110011101001100010010101001011111111101101010101010111100010111110110001011110001100110011001111111110101110111101001100011000001101111101011000111111010011001100011100101110110100011110000101010111101000000001001101010010000010011011110101 1011100001110011111000100101111011110101010001010001111100110011111111010010100011101000100100110110011100100111101111011000110111111100101101101001011110000000100000100101010100001001110001000101101100000011011001111101000000101011010111000110100110011010000001000000111111010110000110000111101101101101001110010001010000000111111111110001100010010001101001101100010100100111111011011001110000110001 0001110111010011111110100100111111001100000001100101100110001010001011110100010100111110111100000010111001001101100101010101101111001000110011010010111001010111011101011010111111110010000100100110010010110010011110110001110001100111000011111001111010100100110001110011110011000110110010010101000000100111100001011010001111001001110101111100111101100110110100100011000110000010011001011010100010101001 0100001100000100111000010110101101101001010110100011000000101001010110100110110001101100111100011100010101110101010100000010010011101110101001111001001101111111111000000001000000000011010111011011000100111110110101100111100100011010010001010011000010011110001011001011101100000001001001001100101100010100111010010001011101101111110100111110110010111000010101000111001101101101010110100111001000100101 1000000010010011110011011110111111110100110101111111101101101101100100010101000110101000101100011000111101101010010100001000000110101111001011110101100111100000110010110111011011011101011000101100011000111100100100000010010101101110100001011000101001001001000011011001110110011110011110000000000110101110010010000100010010011111010001101001000010011011101000111010111100110001010010011111000001000100 1111011101101010000011100000000010111011101101000100000000101011100110110001101001000110101010001000100011111011010000011000000110011101011101110100101100100111000111100100101111001000101001001010010010111000011000110000110100001100111100101110110111011101100011101110111100101111100010110000011001100110000010110100010101011010001000110100101100000110100101001101000011011110000101100010001110000010 1010000001100010011000111111001100001111001010011010110000011000111001110101001010000001011001101111011000100011100011110011100100010111110111100010000111011000000101110010011101001110010011100010101000011011110100111110111000111011101100011110100010010100111011111100100001010110111010110110110011011111000110101100011101000111100000110001110001001100111111001000111001101111111110001110110111110010 0111111101010010001000010000100101000110100010101010011111101111011011010101000100000001000001110000011110100100111011001001111110100100011110000000100011101011101111010001111001101011100101000001011110000111101001000101101001011111101010000001111100001110111110111100100110101101001101010111010000011000100001001000110011100110000010100010000000101010001100101000110010101001100010101101101001100101 0001000001111111110000001101011111000001101111111000111100011101101011010100101110000011111110001110101011000100111011010101101111011001101111110010110101100111010111110010111100101100100100101011110110000001111000010001100011110011011101001010100110101010110111001001100000110010010100101010110000110000101001110111000101111011011100100110011110111110100011011101101010001100100011010101110110010000 0100010010011011001010001111011101000011111111110110111101010000101001000001100000110111001101100000001000001011100111100111101001111001110101100010011100010011100111000011000011001010110110001011010111000011100101101010000000011000110000000100110111101010010111000111000011010010000101100001110010001001001101010110111101011000001111001011110111101100001101111100111101101110011100001101110110001011 1111101101100011111100000110101111011000001100100111100000111011100000111001000101100011110111011101000111001000110110111110011101111101001100110100011101111100110001001000001110101101010001101000010000011010000110000001010010100110001000110000011000010011111100001010101100101011100111001000001001101101001100111110110001111000000110000010001010100101010010100010010111100010101111010110100110011001 0101111110010000111011101001110111101010111010110000010110100001001011110111100010011101001100111110111010010010100010111011000111011011110111110000101001101001101011000011011000100000100000010001110000011010000010010010001000110101010011111110110010011101001100110101101110111100000000111111101001000101000000010001100000111100010111111111000110000001010010101001010100011000000111111000111010101010 1010100011101111000111000111011001011110110010100000001100101000101111111010110111111010110111100110001011010110010111100000111011010101110100111101000101001001100100110110010111101010110011011111011101011101010110100111010100111001001100010101001011111011001110001100111000101101101011001010000110100110010011111100000100011000100011111000110100100000010100010010000000110111001100001111011000111111 1001001010000101010011010110110101110101101100010000010011010110010001000001101111111100100010010111111101111010101111010100110101011111111001100110101010110000001100001100111000111111010111010101000110011010100010000101111110011101110010100011111111001010111100101100100011111111100010110010001000100001001010000110000111110000110000011111101110101000001000101111000011001110110100101001001011011100 0001001010100110100000001100011101100011111011001101011110000011000000000110010101010000000100010101011100110001111111000111100010100101110100111110111011100100100111011111111010011011001100001110101011001011110111101110010110101011110100111101011001000010100111110100111011100001111001011001001000011011010111110101001111101001001110100010011010101000000100010111000101001011011011000100011101111011 1010011010010111111100101101001001111010001101101001001001010001011010100100010111000101110111001100001010001000100010000001111011010110101010101011100100100110101001100111010101000010101000101110101001011110111001100011000011010100000110000100110101101010110011110111010111010100101010100110100101011110101001101000010111101000100011101110001001100111010010110010011111011001110100100011010000101101 0011111001110101110000111011001111101000000101010100001100101101111111101101000101001101110111110000001100111101001000100010111100010101001101101100001100110011111010101011101111000010011110000010000000101001110000101101101111011010110101001000001010010110001110010010010011011101101000011101001100100111111011001101111111010011011001000110100001000010100110000011001011000100000011101000001110011010 0001101100010010110010110110111100110100101111101000010000011101110100010110111000111100011100110100100100100110000000110000000110000111000111110110011010110011111110011100101010010000001011100000101100111110111101001011101000111110101101110111011101111110000010000110001010000101101000100101010000111110110110101110110100110101001101001100101100111110110101001001110111001111111110000001101111000110 0111011010010101001110001110111101010011110011100100101011001000111110101001100001100101110111101011101000111111110111101100000001000101000001110011000100101111011111111111100100100000111001110000001111110111001000111010001011010001010011001100000101111011100100111010011101100110111010111111011110101110100011011011011111110111000111000011000011010100111000010101000110011001011100110010110011101010 0111101000110000100010100010001110100001010101110001111001010010010101001110010110110101011001101100001001111111100111101110001001011001110110011100001111000000101111001101101000101011001101000100001011111101011001011101110010000011110100011001001010100001001000000110011010110110101111110000101101011000001000100111000000111000100100001010000100101011111011111011111001111100010000110100000101000011 1010110111010000100011000001100101011111000111011101100110100100110010111010101101000100000110110011010010001110011000111101110000010010101111101011001011111111011101000100110011001101111000000110001011000010010011110101000000101010101011111101100111101001101011000001111111000111111101100010100100101011100110001101100001001001010010011010111100010100001101111010110000010000111111001110101101101000 0111100110101100011011110101001110100111110111000100010100110100000100000011000001001001000010010111110110001000000110000010101111101101001010000100001000110100010101100101000110011111011100011111011110111111000001001011100000011111011010111111010101100011000111100111101110001011111111100011100101100000010101101111111100001101101110000011000111001111011110101000001111111100000001001100010000010001 1101101001111011001011001100100010010110011000000010010100101000110101001111101111001100001111001101011011000001000000000000110110111001100000100010011010011110000110111001010001101001011001000011011111000000101011011101101111100100011111010110000011000110110010000011110110000110001000100100100111111011100000110010000011111011111111011110100011110001101000000011010101010110111011001110001001000110 0100111101100101110000011011000110010000111111101000110111110111001011111101101011001001001100111101100010011001011000100001000101010001111110100010001110001111110100110111110110100011101011011000000110000011101101101101110010110111001100001000010010111101100111110100011011101111011110000101011010010001011110110011101000011100110111100001111111011001111100011001001110100000000101100100110010011000 0101101000001101010010000010101100000001000011111101111010110010000000000001101100010001011110101111100010100101000110000001000001101100000001011011100111011111110010101011110110111100111101111001100001011101111100011110101110010011010000101110101010001100011110110111011000101110101010011011000010010011000101111000010111100111110011010110010110010110010011111011000001110000101100011001010010101101 1111001011010000110001011110101100110000010101110111101000011111001011111111110011111110100100000000100011101100011000111111001110011111100010100110111101001001101111110011110111110111010100001011010011111011001000011111110000100010101001001111111011000111010001111110001111001000111111000011000101110110110000001101011111100000100100111010000111011101100001110111000110010000000111010010100100101101 1010110111110011001100110100110010001000010111100000011111100100011011000100100100011100011010100111000000111101110100000011111000110101101010001110000011111101011011110111000010000000100011001111111111101111110000111111001000111001111101100010011111101100111010010001101111100011011101110100001101001110011100010100110100000011110011100010001000111011101011111001001000110001011101011011100001011101 0100001011010111001011110000001101101001110000100011110011001011001100011000010011101010001011101001001011000100000011001111010000010101011100111011101110011101001111000010110000100001101101010010100101110111101110011101000000111110111001110111101000011110010110011111001101010001001000111111000111000101001001010101010010100010010111011010010110010101011010111110101000001110010110111101011101001011 0011001010101100001111000111010011111010101000010010110111010001011011110011011010100100111001100010110000000010100001011101101011000011111001010011110010010000000001101101000111101111100010100101000011101011000000000001000011000100001101001100101000000011001110011001000101000011101100111100110001110100110100000100101111010001011000111000000100011001101010101101001011100110000010101011101000000001 0001001110011000110010010100101100100111011111011101101110011111100001000011000111110011111110010011111101110100100011010110011000010111111110110101011000110001001001001101001000111000101100100100110110100010110000100100010011001010100111000010100001010111000111100000110001101011101100111010111100110011011011100111010011000101111100110100001000101011101101111001001110110010010101110100110111101001 1110011101000101011110100011110100010010011001000001010110011001001100001001101000101011011001110110101001100011001111100010110011010010001010111111110000010101100101000001001011101001011111000100110010011101000101110011111010000000011010001101000001110110000001111101011111110111011001110001100010110111011110011110011101011100100000011010110110000001011110111110011001001100010000111011111000100101 0000111110101110110011101010000011010110100110110000110100111100100101010000110111101111100111110110001100011001001001001000100001000101011001000010001111000110100100111110000111011111011000010000001011011000101010010010001110010001100010011010100111100100111101111011001101100101000100101010111101100000000101001000011011110110001111111101110011101000000010111011011011111101000000001100111111001110 1111101000110111011101000100010000010101011101100111100100111010110110100001111011111010011101110001010011110011001111001001011001011011011110010000111101001011111111000110110000011110000110101001101010010001001000111111110111010010011100110010001011011010001101011111110111010010010000001100110001100110111010010010101001011101100010110100111011110010010100011011001110100110111100010011001111011101 0000100010101110011010111001110101110110001100110110000001101010010101011001111011001111111111001000000011110101111001011000100111001110001010100101011101010001001001011001000111101111100110011100100110101000111110101001011011110101110001010110100101100101011000111011011001010111100010001111001111101011000000010110001010110011011111001010011101010010111011000111000101111100001110110101110000101110 1100010100000101101000100000111010000110100110111111011001011111010000111010111110100001000111010100001110010011110000011100000011001000101001001100110100000101001101101000100011110111010100111001111110000010100100000010101001111111010001100110111100001011110100010000011001101011010100101101001001110110001111111101101000001011000000111000010001101111110000000100100101111110111100111010101111010000 0111000111100110110000110011111101001001101110000001101101100000100100110001101000110100000111100010011001011101011010011001001100110111101000111010110111010100100100110101101000001000100001100111110101101011011100000000000111010010111000100100010010101011101100101011001000001010001011001110111101001100101010100001110111001111110100000000011001111100000101111101100111100011001110011011000000110010 1100000110010001100010100100011001000010011010100011110001110100101011100001110001110100100001010001100110100001010101110110100001101011010101111000110010101110011100011100111000011101101010111111010110101011011010000110010100101110011001101100111000001111100001111110100100011100100011000111010000000001100101011011100001011110011010011111010100101111001010000000001000000000001111001110011110111110 1111100001101011111100110111011100111010101101010001010001110011010101001001000001000110010001001010100111010111100101100111100110111000010011000001011001110000110110101100101110010110001100011011111010110010101011011111110011110001101111110111111101000000011000100001101010011101101100101101100101011110101110111100000010010010011001000001001011010111101001010011010011111111101011111000111001011001 0000010001110101110011011011111100000100100000101010110011110110101001101110110110110001101101111101011001101111101110011100011010010101111000010111100001110101111010110000010100101101001000001110001010011010100001110010011100100111111001010110111000011010001010100011100100111000101100000110010001010001111010010111100101110100011100010101001111111001100001000100101110000001010100101000111100100101 1000111111001000000011001100101100100010000111101101000110010100110010010110110011000010000100010001101111001111001111011010011110100011101000010011011011101110001011011110100001000111001110000011001110111011110110010111000100110101110010011110010001111011100100000000011100010100101111111110010001000100100001110100001010100111011110011100010011011101011100000011101010110000010110111010010001101110 1100000001001000111101101101011101011011001001001110000011001101011100110010110011111100010011100011110001110001000010110111101011101101111000011000001100001011000110100011011000001111000010000101001010100011001001110111100001110110101010100001010100001110010010110111101101010011011000001100100111110001101110101100011001010001000001010001001101111001101011100111111110111001001010011101011110110001 0111001010011101000111010000001111011110010111010101111010010010101001011010100101110001001000100011001011101000011011101100010000111011000011010111001010000100011000110000110010100001001010101000111001110011000100000111111011001101110100010101111101100010101100111001011001011000001100111010111111001111110110101110010001101111010000010011001100100110001011100111100101001000010001001001100100011011 1111000011100010111110010110011001101010001101110111110110101010100010010010101110111011101001010110000110100001001110111111011100111100000100000000010111001010001000100111010010111110000111000010100111000001011000000000001001011001110011000100011010101111010110000000000111110010000101110110111100010101100011111001100000011011111010000010100011111110101111111100001001100000111111100001010000010000 1001100011101101010101000111000001010000101101100001100011101001111001100101110100011011010101010001010101110100010010100001011010110011010011010110111110001101100100100000011000001001011110100011010101010001101101001001111100110010010000101011100011010101111010010100101111000000001110101111100001101111000000000001100100011100001101000010100110010011001100011111011010100100101011111111111010001011 0010101000110110111100001101000011100001101100100010001100111101011100000001000100000110000011001000000111111110110101011001110011010101110001001000001000100011011011000101000101000011001011111000111000000100110100111000001100001011011100110101101110100110011011001100010000000010010101000100111111111101101010000100111001110111000010011010010110100101101010000101011010000110010111100101100110000011 1111111011101111011110010000111100000100100110001011110110100100010010110111101111010000111110011100001110111001110011101110000100111101100101100100110001000101101100001010100100001101001011011111000101010010011011100100011101100011001010111001101010100110101000000000111001000110110110000111000110101111011101101110111111100010010001011101011010000001000011111000101000101001111100101101011011101001 0110101111110111011101000101011010000000110111001111111110100011110101001010101000001100001001010100100000001000011101010000011100100011011111111001011110100011110100110001100110101111011000101011110000000010111101101111001100011000111000011101100001001001000111101000001000110001001100010011110000001111000000011000001001001100011101010101001100011110000111011111000101010111000111101110010100111000 1100010011000110111000010011011000100101110110101111110011111010011101100000001100011001111010001110011110001011001000010011010100110110100010101011100101111001111100011100011101100101000011111000110100111101110111100001101110101101101100111111010110010000111110001011100010100011010100101011100011100001111110101101000000010011110010100111101000100010011111001101010000001100011111001100010110000111 0111001000111000111001110101010000111001000000001011110001111000011111001101011101011000011110110010101000111101011000001100100110001011001110100100000110111100101101110111010010111100001001110010101011000010010000110100000001101110010000100111111111001111010001100101110011101110001111010011000000111110100000011101101001111000110000000010001101111111001101101101111010100111110101100100100011110110 0100101110011100010101101110101001000000010001111100011111111101001010010111000000111001110001000011011101100010000010011110011101001111010001010000111101001011001000010111000000110011111001000111101110000010000010000110001010110110110101001110000100001010110100011001011101100000001111000010111111100010000100010111110000100100100000100001111110100010000111101011101011000000111011110000110100110111 1110011101010010101111010110011110101010000101001101000110001010011101101001001101010100101100001111101011111111001100000101001110111110100111101100011100000111010101001101101100000110101011000011110111000000110001110111111111111010010110100101000011111001101000101011101101111001100111001110011101110001100001110010010101101111111111000111011101011001100100110010100110001111011010111001001000001110 0000010011001010111100101001100100011001101101111111110111000100110111000001000001110000001001001100001110111001000110011110011111010000101101010100011101000011000001011010111100110000011001110001101001110010000110111100111011111101110101010001111110000011011110101110100001000010100100001110111001111001010001000000100001010110001111011010111010100001100101001100100110100010101011100111110100111001 0100011011101110110000101011000110110110101110011111001011001101110000110001000010111011001001101001001100110100010011010011110111000101111100000111111111001111001011011000010110000100000111001001011110111011111111010001101010110101011000110101110011100111001101101111010100111101100001110000111111111100011110100101111001100011000111001100000101010010010011000001111010000000000110010010101101111000 1100001011111111011010111111101010111101111010101100000101111001000011101010100001101001101010011000010101110001001000111000011111100001101100111111100000000000010011010011000010001011010110110000101010010001111100110000100110101011000101100100110101101110001001100001101001000101100010001111001101101011110000110110110001001010111000011100101000110010000011010010100110111110101010010100101101100110 0011010010011110100100110111010011011100011100001011001101011011111000110101001011000001101010101001110011111101011101001000101110000001111100000000100111011111101100100000110100111010011100100010100100111011000110100100010110110101101001111100100000100010100110110011011110000100100100100110100010110001000110010011110001000011000000011000000100101100101000010101010010010000001011010101101011011110 0110000000001011100000000111110100010000100000011000011100001101100101101011100011001100001011000110011000010011001011001000100010001000111111000000110101111110111000101101101100101001100011111100010101001001001001001100100011000111011000100100000010011101000010010010010000011000100100010101010101100101101000101001101101110111101011010101101100100110100010110010010010100111000101011000000110100100 1111010101110011001101011010010100001100010000001001011100111100100100101110101110000000110100011011011001110000111011010001111011100100100010110010011100011010100011010000000100111111000100110110000000101010001101110000110111000001001000011011011001010101000011111010011110110010100111011101000100110000101101100001000100110011000100001001010110000110101101110111110000010001111010011111100110111011 1011111010001111011011111011001111100010100001011010101101101000010011011100111110000010001011101101110000010111011110010111111111100111101000111000111101000010111101010010010000000101001101100110001001110011111000110011010100111101111010001111110110111100011011111000101010101110010010001000111011100110111110000011100101111110001111010110011011111000000000001000001110011110001100001111010000110011 0101111101100000111110011011101110011000111100110100001010111101000010101111100010101000101010101110011100110000100010100111101011101000010001111111100011100110110010110110101110010111011000111001101001000010001011100100101011111011101001100011010100110100111110100011001000010001110011110011010100111101000100110000011100010010010001000010010100100111100100001101100111101101111101101001000001000101 0000001100111010111000111000110110111111101110001010111110101001010011011101111101100010110010111001110000010010011101111111110011110001011101000110100100010101100001010000100011100101100111000111001100111100001000000001010110101101010000000001010000110111010100111011011111101100011110000001110110110000010100111100000111000101110011010001000110011100011011001110100101001100011111000111110101110011 1100110000011001001100011011110111110110101101100000100011001010101001101101011110100101010110110001011001011001011010001100101111110100010000110111010100111111000000110001010111110001001001111100001111111111110101000001010100011010110001100000001111011100100101110110011001101001110000010010111011011101111111110110101011010100101010001011000001100101010101101111111000111100111110010011100011011111 0110000000001001100000000100110111111101001100100110011010000100111010011101011000000011101010100111010000001100111110101101011001011001100101011100000100100111100110111111010101000101111101001010000001101110010111000010010111000100000001111001001011000000010111000000101110011110000011011011110110100011000100111111110100001011110010011101110110000101010011100001111100111111100100111001000111101011 0111100100011101010010111011000101011000001010010101011101110000110100111110111101001001110101110100011011111101111001101001010000011111100001000001100011111110110111001001011000111110001011010100101011111101011111111011100110000100111110011000011001010111001101001110101100111011111100110111000111001010100000101100101111110011010111101111111010100101000011001010001111101011000100011100011000010001 0111010010111011101100010010010010101100000010010010111111001000001010111001101101110011100011100000111111000111101000001000100110111011101111011011100110100000011010111001110101111011101011011010101011001110000100010101010011001100000101111000001111011001111010101101100101001101001001010111001010011011111100001000111110001001110110011110111011000011000100111111000100111010011000001011011001101110 0111001000111011000110011101010100100100011011010001000000011011010101101001100000100010100101011011000010001101010010010100110110110110101101100000111001111001010101000001101010000101110111001011011011110000100110111111000100010001101100011010111010110011101100110100001011000100011100110011101011110001101000010111010101011011100010000001100101110110000101101000001111101011000101010000010110010101 1001000001001101010010110000000011100111100111110000100000100110011110010011011101010101001110111101000001111101101011000101001101001110110101100000010001010010011101001111000010001100000011000000101010000111111000101011100010010111100000000100101001100100001000001111000111111100011111110010111110110011100100011110010010101011110111000001100101110010110101100110000110110001011010001010111110111101 1111000000011101001110100001001000100101011110001111011010011000010100100011111010001011000010001000110010110110010110011111111011010010111010111100111101010011001111011010010110000100110100100110011000100101111101111000000101011011101100101110001001111011111000110010010000010111110110001000110000000100010100111101110110000100101101100000001101111010111010101101110011110010001111100000100100101010 1010011111010000001010100111011111010011111000101001000100100000111000001110011011111101011001000000100000111100010110001101000110110001100000011111000110101001011100100100010111011001110010011100000100011001100110001001111011011110110100100101101010010100101001101010101111100101110010110110110111111100001001111000011010000101011011000000010110100010011001100101100010100001110101110111101111000000 0100100000000011101001110011100011100110011011100011000000010110110000101010110100100000001110101001110111110011111110111001101110100100010101001011000111110101000100000110011011001110010100011100011111111000001101100000110101100111000101100101101010110111100011110000111001111101011010000110100001011011111110111101010011110100100111010001011001110111001110101111110001001000111011011101010110110100 0100000101011001110101011011010101111011100010001000110010011011011101010110110101011111101101110111101011010001011011011110011001010111010001101001010110010110001000100001010010001101000101101001000100101001100010011111110110101110011110011101110110001001010111010111101011100011111101110100101000100100001101001011111110000001000111100000110010101100001101100100111000001111011110110110101101111011 0111110111101000010010111011101110010001001111110100001110011111010101111001100001010100110010101111110110110100001110010101001100100011111011010111010101011001100111010001100010011100101101111001011011010010110001000010000110110111010001010101000110111001000100010110010110000110100000010110111101011111001001100000001001011101100000010101000011101100001010001010100010000110100110111110010111100110 0000111011101110011010001101001011000101001111010000011001101100100111101011101000011111100111110110101101111111000100000100010010011100110011101110111000010001110110010101100110100001110000001000101011000001100100010000110010001010011010010010111100110010111010110010100000100000000010001100000100010111001101000111000101011000010011001000101001110001111000011010101011111010000111010010010111100110 0101001110000111001111011100110111111100001110111110100001000110000001110111000100100011100000111010111111000011010000111111011101110000000101101010100101110101100110011111100010010100111110010110000010000001001111001111101010110001100010100001101101010101101101110100100100010110000000001101000000011000111101100011010111101111011011010010010110001101110000101011001110101000011110111110111010100111 1101100100010000101111011011111100101101110111001100010000011100010010100010010000000000000011010111000111101000001100111011100011111101100000000100000001101000110110101110011001100000000111000001010101101101101000011000110111100000110011011001111010100000110100000110010000111110101000110100110101011111010010001000000100011011001001100011110001010010111111000110111101110000001010100110111010001101 1100110110011110111001110100011010110010000110111111111110011001000001111110001000100011011010111111110011010111010010010101101001010111011111001110011001001111100110000011011010001001100100010110100011000101000111111101101111111110100001101000111111101111001101110001110011011011011100010001101010111001100010100000110111101111011001101011110101101011011101100001010000100101111011111011110111011010 0100101101000111111000010010001011111100101111001000001010000101000000110100011101001011010100001011101000101110010011110100011000000110001111010010110111011010110110010010001010101010101100011111111111001100101100101101000110010001111010010111010011100110110011101001000101011111101010010100110001111101001001001000010010001110110101010100010011110101011111001111010101110000010010100011111010110010 1010001110011101000001100011111101111010000100110010101111011010000110001110110101101110101110111000100000100110011100011111001100110001001101111010010101100111111101111111101001001010101001101000000110000110011100100100100011100010100011001111011110101111111000010010101111001011000001110010011111111010000011001111110000111100101111111000001110010100010100100000001110000110001111110000101011000110 1100011010100001010100101011011011001010010000100001101110110110101101000111010010111001111111010010010011001101101111001101010101001110100101010101111110111101111011010110001110000100000001000011101010000101101110101101010000110001110001101111000011110000010000110110011101001100100100001010100111001011001110101011101010110101000100010111010010011100100100100011001101111110101110111110101111100111 0110001000110001111100101001000110011101111000000010111011010010111111011000011000101010100111011111000101001011000111001011111011100001110001011001101010110101010110100000101110000001101000100011101100010101010010100011110110000000110010000101001111001110001011110010110011000111110001001111101011001101110011111101000100111100011101001010111111110100011000011111001110110011000001010100001110100010 0011111110001000010110110110110111111011111000001001100101111100011100011011100100111110010010110011100000101111001111000100000101100110110010110001101010101011110000100000110110101100000000000100100101001100011010001010110001111001011100110011100010011010011000101100100000001111010000110000101011010011001001110101110011101011101111101110111110010101011111110010000001111100011011110011100011011010 0001101111011010011101011011110010101111111011101111101110001011111010111111011111110000101011100100100010010010001110000110001100010000011111000111001011110110011011010001010110101111111110100010010101001010000010010001100001010101100110110100100100011001101101010110000101111010010100110011101010101110101110101101000101000110001111101111101010101100101001010100101101101001010011111011111101011010 0101111100110000010110011111101001010011100011100010111100101100101011101110000101111110110011001011000110111101011101100011001100000110001011100010101010011111100001011010100000001011011001010011100001001010100110111000100010101001100000011101010000100000101100001110011001111101110011111100100100000000010111010011111101011010100111111110110011110001101111111111010011111011101011000100101100110101 1001100101111001010111000111101111000001010110101011101101001101100101000001100111111111001101011010101110101100110110101101011000011100100101110111000011011000101101010110001000110010111110100111101111010101010111011101100100011011011111100010000101101011011111001101111100010101110100110110110100001100110111101001101000001011101001000010111000000000101010000111011110111101000110011101101000111100
C#cTrader Algo

【cAlgo】cBot開発でも新しめのC#機能を使いたい!【Tips】

7/30/2021

4年以上前の記事です。内容が古くなっている可能性があります。

cTraderのcBot開発にはC#4.0の機能までしか使えない?

cTraderフォーラムを見てるとときどきこんな話を目にします。これはある意味正しいのですが、正確ではありません。

確かにAutomate画面から右クリックで「VisualStudioで編集」した場合、そのままではほぼC#4.0までの機能しか使えません

ただ、新しい機能を使う方法がないわけではないのです。少し詳しくみてみましょう。

 

C#の機能とは何を指すのか

「C#の機能」といってもちょっとざっくりしすぎてて何を指すのかわかりにくいので、ここでは2つに大別して考えます。

①言語自体の機能

いわゆるC#の新機能というとこっちを指すのが普通かもしれません。「こんな文法が追加され、こんな書き方がこんなことができるようになったよ!」みたいなのです。

たとえば文字列補完式。変数priceの中身を出力したいときはこんな風に書けます。

    Console.WriteLine($"価格は{price}円です。");

この文字列の中に{}で変数を埋め込むというのはC#6.0から使える機能です。

同じことをC#4.0でやろうとした場合、こんな風に書く必要があります。

    Console.WriteLine("価格は{0}円です。",price);

微妙にわかりにくくて不便。WriteLineで使うならまだいいのですが、普通に文字列生成したいときにはstring.Formatを使わなければならないため余計に面倒です。

実際(普通にやったら)cBotやIndicatorの開発では文字列補完式は使えません。これは実は使ってるC#のバージョンが低いわけではなく、C#4.0以上に相当する機能はcBot開発用拡張機能によってエラーとしてはじかれるようなのです。

逆に言えばこれら新しめの言語機能は拡張機能にさえ邪魔されなければ、コンパイルもできるし動作も問題ないといった機能なのです。

 

②.Netフレームワークの機能

例えばWeb接続なんかをしたい場合、現在だとSystem.Net.Http名前空間のクラスを使うのが一般的だと思いますが、cBot開発においては(そのままでは)使えません。

using System.Net.Httpと冒頭に書いてもエラーになりますし、参照追加しようとしても選択肢に出てこないのです。

「C#4.0までの機能しか使えないから仕方ない」とあきらめるのは早いです。これはC#の機能ではなくて.Net Frameworkの機能でして、.Net Frameworkのバージョンが古いのが問題なのです。

cBot開発時のターゲットフレームワークはデフォルトは.Net Frammework4 Client Profileですが、System.Net.Http名前空間は.Net Framework4.5で追加されたものなので使えないというだけです。

ターゲットフレームワークさえ変えられれば利用できる機能ということです。

 

フレームワーク依存の機能だけでも使えるようにする

先に簡単な②を解決する方法を紹介します。一応簡単にフレームワークの説明しますが、方法だけ知りたい方はこちらへ。

 

そもそもフレームワークってなんだ?

C#やVBといった言語は.Netのフレームワーク上で動きます。要は.NetのフレームワークというのはC#やVBを動かすために必要な基盤です。JAVAのプログラムを動かすためにJAVA仮想マシンが必要なのと同じように、VBやC#のプログラムを動かすには.Netのフレームワークが必要なのです。

例えばcTraderの場合は.Net Framework 4.0上で動くため、.Net Frameworkのバージョン4.0以上がPCにインストールされていないとcTrader自体動きません

「そんなもんインストールした覚えがないぞ!」という方もご心配なく。.Net FrameworkはWindowsのインストール時に一緒にインストールされています。Windowsのバージョンによってインストールされてる.Net Frameworkのバージョンも異なります。

この.Net Frameworkが色々な機能をもったクラスを提供してくれるおかげで、C#のプログラムではネットに接続したりみたいな実際は複雑な処理が必要なことが、たった数行のコードを書くだけで手軽にできるわけです。

(なお、今では.Net Framework自体がすでに古いフレームワークです。.Net Frameworkはバージョン4.8で更新が終了しており、現在はWindowsのみならずMacやLinuxでも利用できる.Net Coreが主流となっています。)

 

C#と.NetFrameworkの関係

C#のバージョンと.Net Frameworkのバージョンというのは確かに密接な関係にはあります。例えばC#4.0であれば対応する.Net Frameworkは4.0です。

(それぞれバージョンの対応はQiitaのこのページが参考になります。必ずしも同じ番号が振られてるわけではありません。)

こういうと、「C#4.0機能しか使えないのだから.Net Frameworkも4.0までしか使えないのは仕方ない」と思ってしまいそうですが、そういうことではありません。

あくまでC#4.0の機能が.Net Framework4.0までの機能をベースに設計されているというだけの話です。C#4.0の機能の中には.Net Frameworkが4.0以上じゃないと動かないのもあるよ、ってことです。

 

ターゲットフレームワークは変更できる

cBot開発で一見.Net Framework4.0までの機能しか使えないのは、ターゲットフレームワークが最初からそう設定されてるからというだけです。

別にcTraderが.Net Framework4.0で開発されていたからといって、新しい.Net Frameworkさえ用意できる環境であれば、cBotやインジケーターまでcTrader本体に合わせる必要はありません。

cTraderのcBotやインジケーターを作る場合、ターゲットフレームワークとしてはデフォルトで「.Net Framework 4 Client Profile」が指定されていますが、そもそも今cTraderが動いてるPCで.Net Framework 4 ClientProfileしか入ってないなんてことはそうそうありません

少なくともWindows10であれば必ず.Net Framework4.6以上が入ってます。ターゲットフレームワークは新しいものに変更してしまいましょう。(自分が使うだけのcBotやインジなら選択肢に出てくる一番新しいものにして大丈夫です。)

VisualStudioの「プロジェクト」メニューの一番下、「 (プロジェクト名) のプロパティ」を開いて、「対象のフレームワーク」を変更します。

これだけで「〇〇というクラスが使えない」「〇〇が参照に追加できない」といった問題は解決することが多いです。

 

 

C#言語機能の新しいものも使う方法

次に①の新しめのC#言語機能を使う方法。要はcBotの拡張機能が邪魔なだけなので、拡張機能が動いてないところでcBotを作ってしまえばいいのです。

 

C#の新しい機能使いたいなら、メイン処理は別ライブラリとして作るべし

結論としてはこれだけなんですけどね。ライブラリを作る際はターゲットフレームワークは自分で指定するため、これもできるだけ新しいの選んでおきましょう。

これによりC#7.0までの機能はすべて使うことができます。以下で手順を詳しく説明します。

 

手順

ライブラリとして作っても、cTraderで使えないと意味がありません。ライブラリの機能をcBotやインジケーター本体のalgoファイルから呼び出す必要があります。

そのため、こんな手順で作っていきます。(cBotで説明しますが、インジケーターでもRobotクラスがIndicatorクラスに変わるだけで、ほぼ同じです。)

①ライブラリ側でRobotクラスをメンバに持つMyTestLogicクラスを作る。

②ライブラリ側でロジックを実装する。

③algoファイルからはライブラリを読み込み、MyTestLogicオブジェクトを作り、メソッドを呼び出すだけ。

では一つずつ見てみましょう

 

①ライブラリ側を作る

VisualStudioで新規プロジェクトを作成します。

新しいプロジェクトの作成で「クラスライブラリ(.Net Framework)」を選んでください。

次の画面で名前やターゲットフレームワークを設定します。

名前はなんでもいいです。フレームワークは自分で使うだけであれば、一番新しいものを選んでおけば、上記②の機能も問題なく使えます。(デフォルトで新しいものが選ばれてると思います。)

あとでcBot本体から参照するときに作成した「場所」が必要になりますので覚えておいてください。そのままであれば自分のフォルダのsource\reposの中だと思います。

続いて、cAlgoのクラスを使えるようにcTrader APIのDLLを読み込みます

ソリューションエクスプローラの参照を右クリックしてして、「参照の追加」。cAlgoAPI.dllファイルを探して、追加します。おそらく PC>ドキュメント>cAlgo>APIにあります。

あとは冒頭にusing文を追記すれば

using cAlgo.API;
using cAlgo.API.Internals;
using cAlgo.API.Indicators;

これで、cBotを作っている時と同じ感覚でcAlgoのクラスが使えるようになります。

あとはClass1の名前をMyTestLogicとでも変更して、こんな感じの雛形を作ります。パラメータを持つcBotの場合は、コンストラクタの引数にでも追加しておいてください。(インジケーターの場合はOutput属性のIndicatorDataSeriesも)

namespace MyLogic {
    public class MyTestLogic {
        // --- フィールドにrobotを持たせる
        private Robot _robot;

        // --- パラメータがあればこんな感じで
        //public int Period { get; set; }

        // --- コーディングしやすいようにプロパティ化しておく
        public Chart Chart => _robot.Chart;
        public Bars Bars => _robot.Bars;
        public double Bid => _robot.Bid;
        public double Ask => _robot.Ask;
        public Symbol Symbol => _robot.Symbol;
        public string SymbolName => _robot.SymbolName;
        public Positions Positions => _robot.Positions;
        public PendingOrders PendingOrders => _robot.PendingOrders;
        public DateTime Time => _robot.Time;
        public History History => _robot.History;
        public MarketData MarketData => _robot.MarketData;
        public IIndicatorsAccessor Indicators => _robot.Indicators;
        public void Print(string msg, params object[] parameters) => _robot.Print(msg, parameters);
        public void Print(params object[] parameters) => _robot.Print(parameters);
        public void Print(object value) => _robot.Print(value);
        public TradeResult ExecuteMarketOrder(TradeType tradeType, string symbolName, double volume)
            => _robot.ExecuteMarketOrder(tradeType, symbolName, volume);
        public TradeResult ExecuteMarketOrder(TradeType tradeType, string symbolName, double volume, string label)
            => _robot.ExecuteMarketOrder(tradeType, symbolName, volume, label);
        public TradeResult ExecuteMarketOrder(TradeType tradeType, string symbolName, double volume, string label, double? stopLossPips, double? takeProfitPips)
            => _robot.ExecuteMarketOrder(tradeType, symbolName, volume, label, stopLossPips, takeProfitPips);
        public TradeResult ExecuteMarketOrder(TradeType tradeType, string symbolName, double volume, string label, double? stopLossPips, double? takeProfitPips, string comment)
            => _robot.ExecuteMarketOrder(tradeType, symbolName, volume, label, stopLossPips, takeProfitPips, comment);
        public TradeResult ExecuteMarketOrder(TradeType tradeType, string symbolName, double volume, string label, double? stopLossPips, double? takeProfitPips, string comment, bool hasTrailingStop)
            => _robot.ExecuteMarketOrder(tradeType, symbolName, volume, label, stopLossPips, takeProfitPips, comment, hasTrailingStop);

        public MyTestLogic(Robot robot) {
            _robot = robot;
            // --- パラメータがあれば引数で受け取ってセットしておく
            // Period = period;
        }

        //------------------------------------------------
        // 下記をそれぞれ本体の同名メソッド内で呼び出す
        //------------------------------------------------
        public void OnStart() {
        }
        public void OnTick() {
        }
        public void OnBar() {
        }
        public void OnStop() {
        }
    }
}

Robotクラスのプロパティやパラメータはほとんどpublicなので_robot.の形でアクセス可能ですが、いちいち書くのが面倒なので直接呼び出せるようにプロパティ化しておきます。

Robotのpublicメソッドも、PrintやExecuteMarketOrderなど頻繁に使うものは直接呼び出せるようにしておくと便利です。(他にも必要なものあれば加えてください。)

 

②ライブラリ側でロジックを実装する

中身を好きに作ります。ここはいつもと全く同じ。上記のOn~にロジックを書くだけです。必要なら別メソッドや別クラスも自由に作ってください。

一通りプロパティやメソッドを用意しておけば、普段cBotを作ってるときとほぼ同じ感覚でコーディングできると思います。

動作確認がてらこんなコードを書いてみました。毎ティックスプレッドをログに出力するという特に意味のないcBotです。

    public void OnStart() {
        Print($"{SymbolName}のチャートで開始しました。");
    }
    public void OnTick() {
        Print($"スプレッド現在値{(Ask - Bid) / Symbol.PipSize:f1}pips");
    }
    public void OnBar() {
        Print($"{Time}:ローソク足が更新されました");
    }
    public void OnStop() {
        Print("停止しました");
    }

ここまでできたらCtrl+Shift+Bを押してビルドしてライブラリ側は完成です。

 

③本体(algoファイル)を作って呼び出す

algoファイルを新しく作成します。MyLogicMainとでもしておきましょうか。

作成したらVisualStudioで開いて、参照に今作ったライブラリを追加します。

上記ライブラリを作った場所を開いて、MyLogic\bin\debugの中にMyLogic.dllがあると思うのでそれを参照します。

今回はこれだけでも動くのですが、あとあとのことを考えるとターゲットフレームワークも変更してライブラリ側に合わせておく方がいいでしょう。(上記参照

あとは簡単、using MyLogicを冒頭で宣言して、本体側でMyTestLogicオブジェクト作って、各所でメソッド呼び出してあげるだけです。

using cAlgo.API;
using MyLogic;

namespace cAlgo.Robots {
    [Robot(TimeZone = TimeZones.UTC, AccessRights = AccessRights.None)]
    public class MyLogicMain : Robot {
        [Parameter(DefaultValue = 0.0)]
        public double Parameter { get; set; }

        MyTestLogic _logic;

        protected override void OnStart() {
            _logic = new MyTestLogic(this);
            _logic.OnStart();
        }

        protected override void OnTick() {
            _logic.OnTick();
        }

        protected override void OnBar() {
            _logic.OnBar();
        }

        protected override void OnStop() {
            _logic.OnStop();
        }
    }
}

上記の通り進めているのであれば、algoファイルの方はこれをコピペでいけるはずです。

基本こっちのファイルはパラメータを追加するときくらいしかいじることはありません。ここまでできたら閉じてしまっていいです。

注意点としては、ライブラリ側を変更してビルドしたら、本体(algoファイル)もビルドしないと変更が反映されません

面倒に感じるかもしれませんが、本体(algoファイル)側のビルドはcTrader内のボタン一つで済むため、大した手間ではありません。。

 

お試しあれ

最初だけ少し面倒ですが、簡単なcBotやインジケーターならともかく大掛かりなものを作るときはこの方法を使った方が結果的に効率は上がります

もしこの丸投げ型を頻繁に使うのであればライブラリ側のひな形をもう少し作り込んでおいた方がいいかもしれませんね。この辺はまた気が向いたら別で投稿します。

 


まだコメントはありません

新しいコメント

コメントは承認後に公開されます。承認まで次のコメントは投稿できません。

cTrader's Life

© 2025 ajinori