1010001100000010100110100010011111110001110011100111100011110101000110111011100000111001010011000010011011110010110011000100101111011001110010010011110001101111010111010000011100000000011101001110110000000111110011110111001110111111111000110011100101000101101100110011001101110011111001010101000100010100110010101101010000111100010100000111111111110010111000111100011110001100111111101010010100010010 1110001001111000011000010000010001101011000100010010100010010001110101001010100011010111011100010001000001101100101101000100100100001001010111101100000101101011110100000001001110000111001000001010010010011101111110011000011110000010100001011110110011100010101111100111111010011001000001001011000100010101010111001001110110100101100000110001100010011010001001010101100111101111111110011010111011000001 1100101001000111011101001111001010111000011101100000110101011001010101110101100001110100110010010011010000111111010001100111000000011011100010011111001010100100111011010100011101000110001111110111001011100010111010100101011111010100001111110111101001011010110110001010100110100001011001001001000100011111001101111101010110111110000010000110110101111011110001101011101110101001111101100110000111111001 1100110011101101000000100001101011010001100011000010000110011001001101001110001001111001010001101010110110010000000001100110000100101101101000011101011011100110101000010000001000110101100111011001001010011001101111100110100100100101111101000011000001010010011001000001000010000111000110101000000000000111001111100110110101101110100100000101000101010111001000110111010001000011110010000101001101010101 0001010001101111101010011101100111011110011000100110101000100011111100010101001100000010100010010101100010010010001111100111111111000000110001111011010000111011000100010001010101011011111110111011111011010110001011101110011100100100010110000010010100110111110100100001110101111100100101110011111110001100100001110111111000110000011111111110000001110011111111111111001011010011111100100101110001010010 0001111101000000111000011000110000011110000001101001011111101001100110000101000111011110110011001000101001011011110011011000111011110001000110101111111110101001111100110010101001011110110111111110011001010011011100010001011000011001101100110111110100000000101011100000010010110010001011010000111000110100001000000101101001010001101110111111011111001100011110110011100101010011101101111011000001111111 1010001100011110001011110001010100100000000011110100111100001100101001011000111000111001111001100111111010110001100101010010110011111001110001001001000101111110111111110011110101001000101000011110011110011110101011101101101110000110100111110110100010110100110011001010101100011101011000111111100111011111011101110011001101101000010111110011110011101100111010011101111111001100110010000010010001110110 0010010011011011001111110111011101001101000100110010111101001100100010101010011010100110100101100100111110000000100101111000111001100010101000111000111100100101100000000010011110011010101011010101110111000100011110001000010000001000110100010110110101011001101100101000011010111011110100100111111111100111010101011011111010101011100001100111101111110001111101010010100101110000011101100001000100010110 1110101011101001100010010100110111010011000011110101000001111010000010100110000001001101100011001101100111100000011010100100111110110110110110101111000011001001010100001011100001010011001101011101100001101000011011111010011000111100001100000000101010111100010011110000011111011010001110101010000100011011100000001111011010001010110000011100100101011100100010111110100100001000110011010010001001011010 0110111001110100111100011011011101101010000100010011001110111101100011000111111000000010001011101001000111001100000001110100000100010110011111010100111001000111111010011101000110010000101111110010010001111000011010010010110101011101011001001111110011101011100000101100011000000111011000001101011001010100010100000000000100011101011001111100110000010000001010101001100001010010011011110100111010001101 0111000001110101100110100100010110010001011111001011011001101000001001111111010000011111110000100101111011111101011011001111000010101110100100110111110101011100110100010111010100111100111000110000010011100001101011001100010110011111011011000010000011101001011011001100100000101011100110001101000010110100110110111010111111010010011111011000010001011001111111111010000001111111100010111010110000100100 1111110001110000000010111010110000111101111010000010110011100101000111000100110010000010101111100001100100001100110011100011110101100010001101111111000010010110000010001000000000110000111100110011111111001110001010000101000000110011101001011101001111110011110100111010101110100011011101111111111101100101010011011110001011111100101111111111000101001110010000100011101101010000101110111100110110000110 0111010010010000100100101001011001000010011010100100100100101100101111101010001010101000100111101110011010111010111000000101010111001110110001111100110111010010111001111101000001001001000100001100100110111010111001010110101111110101110010010001100111001100011111111110010011001100000100110100010101010010100101111100001100100000010011010111111011001001000001001000011110100100110001001010001101100110 1000001110110000000010111110101000010010101001011101000100010010101001000010000111010101000000110110000110110110111111111111110001001011000111111100010010001111111100110111011000110111111101110111101101110011111011101011100000100110001101101001111100100000101001110000101101011111010001110100111110101011110110010000010011001110001101110101001011011111100000001001011000111011110010000000110100101010 0000011101111101100011111001100110111110011100100111100110111011101000010100101111001000111000101001001011000011001011100010110101001110001010001111010001001011111111001101000000111110100100010011001110100101111011000010111010011111110111010100111011111101101010110101010111010000100100010110001011001111101111111101100010011100111010100000000111011111100101100100101100000011110111001010101111000000 1111100100110100011001001101000111101000100011010010110101010100100110111011111100100111010110000100101101100010011011000101111000010101110110000111000010111011100101001110011000000010000000111100101110000001010001111111000011010000010001011111101011000000010010111011110000001100110010010110011101111000111111100100010101011110011110111001100001000110001101011111010001110111010110010001101110000111 0101100011010101110110111010000010000010010100100111000101000110000000100000111001010111011100111101110110010100101101010011110001101100101111111001101101001100000111101110001101111100110110010000101111010101101110010000010010011100101011011000101101011111001111110000001111000111010011010101000110000111011001011010111101101100110110000111011110101110010001000000000111011001111100101010011011001000 0100011111001011100100010011010101010111001000011001001010100110100111100110100100010010010000110100101010111000001000100010001101100111001000000110010010011010101010100000100000100110000100000010101011001101010110111101110110011111001111111010100111011110000110111001110100100101101001010001010000010100111001001000111101110010010110101110111000111010011100011101001011001011010000011001010100110100 1010001011111110001010000000010010000010110000100101001100101011100000110001001110110011100101110011101000011110110001010000001001000010010001001110001010010101011111001100110110011101101111101011110100001100100011111100000010111110100010100111111010111110010011001110101011110101011011111011001101100110111000011100110111011010110000001100100101001111000110001000111110100010001001000011100001111110 0001001001000011110111001100101000010001110000010111100101111000001110010110111111010101110001110101010100011011001011011001100110110110110011011111110101110101000001100111111000101010110111110100010001000001010111100011000101010111101001100010110110011010111111000001111010011000010011010101110011110001011100010101110000001100101010101111111000011111010100100100000001000000111110110100011101111100 1110101000101011110011101000101100110011111001001101111111011010001111011100010111111001001111111010010101101001110101111111110100010001000010000100001001110000111011001100010101111001110000011100010001001110000010110111101111000010000110000001100101101100010000101011111100101000100011111010010111110010100101110011011010101110100110011011110101111011010001001110101111010100010011110000011111110000 1110011111100111101101111111100001001110001001000110110011111111001100000011011011000001111111010110000011110001010011010111100110111010101101101101111011100011010110011011110011100011101000001011110010100100111100101111001101000100010111110100001001010100111101111011011010110111011010011111001111101001100101000011010100110101101111101110111011011000100110110000111100000010000001011011001100010110 1100000110101101101011101111101000111100100001011101001000011110001100011101111000001001001110001100000010010100011011011010100111111001110111100100111001100111111000010010011111000011110100011001011101010110111110010001000001111000100101001101010000001101000101010000101111011101011000111100011100101001111101010110000100111111101010000011001111001001001101001110110001000011111010000100000001000100 0100111001010001010110100110011001100001001000000011000001000001101000000000101011010001101001010000001111100001101001001111011100010001110100110010100100010111000010011001011010001011101001001011100101001101111111000010001001010101011010101000100001100101111100111110100111110011100010101000110101101001010100010000000101111001110010011010111111011000011100111101000110101001111111010100000100110101 1011010110111111001000111100111111101010011100011001110010110110000101101100011110011000001111010001010001101011110111111001100000011011101110101001010100001011101111011000010000001010111011110100110101101011100000011100011000000000000010000001101011110000011011100001111101011110101010111100001100001011011001010110011100000110110110000011110011111111000010000001000001100101101011111110010011000111 1100100010100110111000001010001001010101101000011100000000100111110000100011000100001010000000000000000110010000100011011001111111100100001001110001100000100000101111000101010000011110001010111110101011100010101001001001010110000011100011110001011011100111001111000110111100101010000110000000000100001000111000101010011010011110111110101111100010010000110110110101101010000001000110011101100111111111 0011111010111000110010111011110100111000010110011111101100011000111110111110000001001111010101010100001110010111101100010010001000111010010111110001010110101000110011000101010110000111001101101110100110110110111001100001110111000000110111010101101011010001111000110101000110111011110100110100100100001111111000110000010001111000111010100000010011110111001100001000101000100100010101110010011100001100 0000001000100111100010000011001000100000100100001010101010100110001010010110110001100010011000000110110100001110110001100001100001011010110000101111101100110011101000100000001001001010111001000111000000101100000111000000100001001010111101110010110111010101000101011101101010111000101000100001100101011010110001111111110100100110110001100110001001000000100010100010001111001110011010101010101100101100 1001100100101111001010110101010101010110010010101111101000101111011000011001001111001101100011110111101000010111110011010001111100100001110001101110011000011100111001000001111101011110000010001001011111011001000000011111111110101010110110100010110110101111110110111111010001111010000000010011110100110111110010101000110000010010110111000110010010111010001101100001100100000100011011000000010110100001 1111101101111010110010011001100100110100001101001111101100111010100001011111110101001101001000000111001001001011000111100111110001100111011101011001001010010010111000100111100001011011000011001001101110011001100000010011110010010010101000011001101010000010000100111001011111111001100110011000001111100000010101111001001101011000100001100001001010010110011101011010000110100111111100100011110001110000 1000011100100001000011111100010000100111111000010000011111101011011101111011111001011110111100001111010011100000111110000100100010100010010101011000001100010001011100110001011111110011011111001100100001010010110001110101110111110110100100001010010010000010010101011100001110101000001111011100001001111000110111100101011101100100011101110110110010010000110101101010010011010100100101110111110001010010 1010011110001101111111010000001000101010100010011110101111000011011100110101010111100011000100011000000100100110101100011011101000000111100010101001010011101110010100111000110010011011010001011101010010000110111110001001001111010001110010001010100011001110101111001001011000100100011111001001011101101010100110101111000000101001010111110100011111100111110101101010001001001001100100000010010110001000 0010111100010111001001000110001111101110000111111001101011110001101011110100000111110101101100010111101111001100100010100011010010110110111000000010010000101101101011101010101001001001110000010000011010111101100011000111011001100011010011001010001101010001110110010111001100010001011100100101111010111111011101001111001110111000001110101100110110111111010001001000010011010101000011001010001101010100 1111110010001001011010110110000000100011000110101111100110000011111110110011010011001110001011011011011111100010000010110101010101111000001000001001100011111111010001000011000110110111110111001101110010010111100010111111110101000101111101111110111100010000101110100011001100010111100100000011111000010110010001000101101110100110111001100011000001001001111110001000001000010000010010000010000100001011 1001110111101010011101000101001010001011100000010010011100100111010110100011100000111110101001011010010111101100010100100001011000011110110000111000110001011010101010000011111010110011101101010100111001011101011100100000011110101111010000111110101101010101010010011001000010101101000100111011011101100000110100110111100011001001000101101010011101000011101100000111110111011100111100101110011101111111 0001010101010000110000100100110110010111111000101101101100010011111010100110011000000110010110100010001101111100000001011001011011100001011011101010110111010110100100100010001011110000101100101010011101101010011110010000000000111011010111111011110001010010001010011001000000110000001110000100110100000100100100101110000101011001110011110100101001110110100010110000101101111010111111110011011000100101 0101001110010011110000011100000000000100111110110111100111110010100100000100110010101001011000010110100001110101001100011001010001010111011100000010101111100011100110101010110000110110001111100101001111010101111010011111101111010100110101110011110011110101111011010001010101011110101011100010011010111110100101000000100011111101000111010011001101010011000110100011010100110111000100010111010111000000 0100001011001001101011001101101001001100011000111001111101100100100101001010001001011010011110010100100100011011100111010000101111001101000111111111000010010010111001011111000100101111001101111000000111111100101001000001111111110110111111110111100111101100001111010100010110111000011001011110111010010011000000111001001110101000101001110011101110000101011011111001100011001101000111110011010000000101 1111011000101100001100100101110000010010010011101010011100010101111011111100101100000001101101111100011111001111010011111111100111100111111100011000110000001100010100101000000101010101011000010010010101010101110101010011110010100111010011010001011001001001001001100010100011001100010100011010111100011111011001100101110101010001111111000110000110001100111001110111101001111001000000001110110100101100 1001001111001011111000011111101010101111011100010111100111000000100001011110100111111110001001111000001111110010110111011011110011010100110111101110110101010111111010000110111001000000100111100111001100011101111010111110011000111101000111101110101000110101101001101010111001111111111001110000110000001110110000111101011010110101010000010100101001011011111100100110001100110100101100111101001011100111 1011001011111110000000101110101000001100000101001111101001011111110001001001100011010010110010100111000010111111011010011010101001010111001010000000011110010010100100010000100010000011110011101000011000100110101000011100001000011011001000010110111101000011010111001010001100010111101100111100100010011000000011011100000110011100110011001111000110001000010001111111100001001110100001100100011101100110 0010001000001111001100011001001001011001100000111001010001010010110111111011010000000100100001011110010010000001101011101010111110111111011011000010000110111101110001011001010100111101001101110100001100010111110100011010101101000001010011010011110011101001010011111111010110010000010011101010011101101011101001110111010011100111001110000011111011000100011111000101001010101001100110110100011101100000 1001010101000100011011101001111000000010010001000100100000010000110111100111110101010011000011111011110101101111011010110010011101011110000000110111100111001111100000000010111011001110110101001101000001010010000011111001111110000100111100110111010110101111111010001001100111000101010101101000110100100111010000001000111010101100001011101101001000100010001110110101001011111001100011111001001010100111 0010000001011000110110111101101011100111011011011001110100011110101010101110110000101011000011001000001100000111100100101101000010001100000010001010011010111100100010110101110000000000101001000100001010001010000001101101000111011011001110011011101101000100100010001010011010011101010111100111101001100100101110110110010001000000101010110111110101000000110100011010101111011011101111000111010001100000 1100100010111110001100110111100110000101011110001110100011011001011000111000001010111000011101110110111110011011001110111101101010111010111001010011011001001010111001001000010110111111011100000111110101110001111011100000101010010011101111011010011010001010101100010100100101100100010100000011001111100111101110000010001101111000111000100001100100111010010000000100010010000100010100101111100100110011 1000110100111100101011110011000111010001011100100111001101001010110101110110110011001010000100010100010110101110110100111111101110111000111111100001000100101010101111100011110101100100111011010110001010010011001110110110101010100110100001111100111011101000110110101111111111000001010010000010000111010001011101110011011100101110111000011011100010110011010011101011111010110111011010111100001100010001 0010001100010110100101101111001001111110001111000000101110111101100000100011101110100010110011101101010000000101101001010100001111111110111101011010001011110001001110000010010001110110010110010111111011100111100001001000011110010000010100110010000100001011000101110100111100101001101000101111000011110101100010000111110101111010111101001111110010101100001100110001111100010001011111000010110011000100 0110001010100000100101000001010000110100000101111000110100011101111111111101001111111010011000111111101110110111011000100111011011101101010101001000110110101011100100110101000000010100011010000001101111111110001110010010100011111010111011011000010101011010011000110111000000100100100010101001101101110101111000111010010100011011111010111110100011010000110010000010110010001111000011111110010111010101 1110001011110100011111110011111011001110111110100101111010010110110010000110100101000011100100001010011101110101101110110010011001011011101111101011001001100101101100101111110100111101011111000100100010111101011111101011001111110011010101100011001010000011011010010001000100100111110001010100001100000111011110100011000100100111110000000000110101111010011010110101010010011100100101110001001110011010 0110111010010100100001001001001111111110110000010111111110101001100110111111111001000111101111101010010100100010010010000000100011101100010111101101001010100010111110101101010100001101011011111111001011011111011100011000110101101010011101001001001000110100000111000101111000101010011001101011101010101001111110011001111011110101111011111000001000010110010011100010101110001010101110011010001100110001 1101011001101111101101111111110100100110010000011101011101111011010011110000011101111101111101000000010101011001100001110001000011101111011101000101101101111011100110100011101101110101001110110100001110011100110111001001001011001010000001000100110010100110000000000011010101000111101101100010100110010000101000000111010101010000011010111000110000110010011110000010101011011101001111011110111010001010 0010000111101111110111111001000000000000101111110110111001101011000101000110001010010111110010101111100100000000111001100001001000111011101001101101101011010001011010101010010110010100001100010111010100111011100001001101101011010011101010100011011001000101101010000000011100110001011111001010001000000011011110011011011101100011111111101000100011010000011010100001110100111100000001000001110110101010 1010001000001000000111000101110000000010000111101001111010100100110011101101110001111111100001000001110111111101010010010101110101110011000111111000100001100111110000100001011000010010010101100011010010010001110000010101000110111011001000110111001011101001111011100101011101001110101001100111111110110101100001110001101111001000001000010111111101110111110010101010001101011110011111010100101110001110 0011000010011001011110110101111111000100000011101011011100000011101011010111110100000000111000100000001110011100001110111000110110001111001001010101100111001100011100101001011000011110011110100000110110000111111011010101011111101010000001010001001110001101011000111100011000101111000000000001110111000011110101101111001001111010001101110001001111010001100010001010111010011100101110100011011011110000 1111000100110000010010011100100010110100010110010100010010101110001111101101010011101010110101011110100111000010111000011111110110101100000010001001010011101111011001010011101010000011010000110000011101100010111011101000110100010001111001101001111011100101101100011101001100001100100110010001011011101011000010000001100101110001000101111000001101011001010011110010111001001011110010011011101010110111 1111001101110101110001000110010000101000010100100010001111101110100011011011001110110110001011011001001100001001111111010010010011001010110010000011011110011010000000010000001110101100011111011100000010100101000101110101010001001110100001011001010011001101001100101011011110101011100101110101101100101101101101000110100000111111000110110111100111101000001100011111101000001110000100000011111011111011 0011111100010110101001001010111010101110111011001011110111000000000110010100101000000011000111001011110010111101010101111001111111011100101010010101010101001100000111011110111101010010001000010010000100010011000101001001100011111100000101000001101101000011111011101011100101001011111101110000001110101010000010101001011100010000101111010010011111011001100101010000001000111100000110001001111111000010 1001010011010000001011111000010001010011101000100100101001100011011001110001111110101011011011010110000101110011010101010011110001111111001111010010010011001011000000100011010110000011100101000000101000001100000111111010100011011000011011001100001111110011001111011110101110100000010100000111000001010011011011001011100011010100101111100101110000111110101110001011011100101101111110000101011011100100 1101111010110101111010101111111001001000011001010010100000100110111110100110101011001110100100110001101000111000110010011110011000100010101000101110100001100011101110010100111000100000010110000000000110000100101111100001010000000100001111011110101011101001011011110111000100101111101100000001011110000001011101010001110110011011000010000101100111100100010011010110000101000110110100110001100110100010 1010111100000011000111101000001000000111100101110100110110111100100100110010000111101100010111010101000011111110001000000111111000000111110011010011011111000010100000000110110000001100001001110100101110010011111101111111101001011111110000111101001011111011000110111111101101101111010100010011100110011001101100000000100001000001001000001001111010100101101011101000010011111010110111000101111101110101 1001011100111101000101001110100011001001001001011000001010000010000111001110111001000001000111000000011001001110010000010001110011000001110011000111000010001111001110100011001010010101000111000011110111101111001100011010110100110110110100100110101011001001010111110101010001000111100001100101011100101010111111101010101101001111011000011000011010100110100111000001010100100000100001100100110100111010 1010011110010011101101110101001110111101010101000001011101010000101011111011111110010010101010100001001011100100001000100010011110110100110000010101101001101011011001100010001111110000101101111010100011111101011001000000000010110000101001110011100000000001110100101011110100000000001000101001010101001000110010111101010001111000010101101100010010011000101101010000000011010100101010011100010010101010 0110010010011111111100001111101011110111000110110110001000111001100111000110110100011010100110100011100111101100001100101001000101111101010111100001110011111101100010001001110111001111110001010100000100111001011101011101011110011111111111011000001011001111001000010011000110000011101101110110111100101011000000100010011011111000001101110011000010111001111010000110111001011010100100000011011111000001 1010110000100100100111000110011010110100001101101001001101101101110110100011111001010000101010001101010001100111111110110110001000110100100000111101001101101100111101101010101010001010011000101000001010000100000101010010100101010010001000110110111001000001111110001110001101100000001101101000110100110001011100001000000001001110011100000000110110101101101011010011000110101100001100110111101001110101 0010111011000110111100000001011101111111100010010110100101101000110001111111111100000101000111100010100101101001001010011101111101001111111100101010011101010000001010000000001011111010110111101000110110100010001111010000101011000110110001011111010000110010011100000010110011111010111010101101111110101110011110111110001010011111101011110101111001000111010001011101001101000111101001010100101111111000 1011001000110001101011111001011000111110111111000100110100100000011110011011110101011101111011111010000110000101111011010000010000011001110111110010110011001010011100111101101101100111111110111001010001100010000110001010010001010111100000000101010011010101000000110110011110100010011111101011000110101000010111010011110111010110001101111111101111010001001110001100011010100011000011111111110001010001 1110001011101010101001001011000100011111010100011001001111111111110111100111000110001101111010101111011010010001110111111110001110000101110110110001000011010000100001010001100011110100001101001100000101111100010010110000110110011010010001011001000011010100010001011100011101001111101011000011000100001101101000100101011010110000100000011001001101100010000000000010001100011101100010000011101101111010 0100100101000100011111101110111000001001100001100100100000011011011110100110011100000101111010000011001010101000010110111000001000001011100000100011101001011010101111001001001101001001000000010000010111011011100001111011101110100000000001001100111010111100101100101000000001001111011110000001010101101101111111110000011001010000110100001100111010000111010110000100011111000101000000101000100011110001 1111111111111101011000011101101011100101010000111000011110111111000110100010000100011100101010011110010010011001100011111110000111011100011001001100001101010111101110101001000000001010111111011000100111001011110000110010101110000101001101011000110001000011100101010101000110000000010011000010011001011011110111100100001011100101110110100000110111010100000011111001010101110010011100101001111100111001 0100110101011111000100111100100111000110100100011100010100001001001111111100110101111000010001100001110011000010110000001001010001001011111000110100110100001110010001000000001000100010011110111101011100010101011011010100110110100000101000011101001100001101110010100101100001000101100110100011011111101101001111010011101111000000000111111110110011111010110011011100011100001011010100101011010111001100 1000110000000100101110001100110111111100001001110101010010100100100010110111001111101000110011010100101100101110100000100011001101011010011101000010111001110000111000010010011110011101111110100110001101010101111011001011000101010010100001111000100011011011111010111110001111110001111101111001000000001101111100010110001001110000100101101001111010001110011010110001101101110110000110110011100011110100 0100110100100110011110100001101001011011001010011000101010010101010000101001111001110010011011111111111010000100111110010000100110100110000000110001010101100111010000000111111101010011100010100111111101101111000001000101000111011000101100001000001100111101011111010001010011111110110100100111011101110001010010000000111101000111100100001101011101101001000100111110010001110001010100000101111101011100 0100101101001111111010001000110001100001000101111010100111010101101000010110011100011001000101101110001011101101011011011000111000101000111111010010110110101110001100101110101110001011111011110000111111000001010010000010011001110010000110110111101001101100101100111001001010000001101101010101110101011001100111000100110000101101001111010000101010101010101111011111101111010101001010000011010010100100 1110001010110101001011011111010101100111100001111100011111101101001111111000011001001001011011111101101101111111100000010111110011111010001001101110001011001001000010000110101101011101011000011010100001001011011111011110101100001000011000010000010000110000000111001010010100100101110110011101001011000010111000100010111010111010101010011000001001001101001111010100110111000101111011011011101100000111 1101010100010110101011001110001100111100001010011011100100111110100101100001001100011100010111001011101101101001011111111100101011101100011000011110111001101010100000001111100011111011100000101011110001001001001111110101111101010101001101000010011100101000011010000011110111100011111101001110111111010010101011000000001000010101000010100101000110100001101101110111000010000011010110100001001111101110 1011110011001011000011001110101011111110010111010100000000101110100101110010010010010100000101011100000001010010110011101000010000001010100000101110101011110111011101100111011101111110011000000000001100001110110001001011000011010101111100000001011000010011100001110110100011011011101110101011010101001010101110101100110100011101001101000000110010000001100000011010001101111010001101011111000001101011 0000110110001101111111001001000111000011000001010010101011011001101000010011001010110110000100101001011000100111111110100100111111100000110000111001100111000101000011101011100100000100110001010100010111110101110101111110111010100111010010011101011001000110100001000011011010100100000001111100001001100011110100110000110000111000000000111011000010000101001100000101110101010110110110110001010010101001 1111101111111101111011111101111100010111000110100100001110000000110111001101010011000011000100101001101001111111100001010100110000110000011110001101111100001100100001011010010100111010001000010010001010101101010100000111010100101000001000110100110001010101100100100100011010001000010001001110000100000100101010011111011101110100110111011110111010001100001010001000011100101011110010000111110111101001 1000110000001001100001000011111010110010110111100011010000101011001110000000101111000111111110101011101111001000101010111101011001010110111100000001110110010100110000110000111100110011001011000001100101101001010110100110101010100001011110001101111100011011111101000010010100100010111010111101010101100111011000010111100111100010101101100010010100101000001110111010100100000100000111100110111000001010 0000111000101001110100001001010110111010001011111100010001010111100100010011001000010001101101100011111000101001010111111000000001011101111100010110110011100001011111100011110001001111101100100111100111000110111001100010110011010110000001110101001010111101110001010001100100100110001100010000110101101000111010001011100011010100001000101110010111110100000101101111010001000000111101100011001001011111 0010000100111001010001110010110011011000110110010111100000011010101100001110000111101110011011001000101111111111101011011110011111101011000011010000110010010100000001100101100011011101110001101001001100100111011100010010110011101010000001101110110010001011001100000101011110100100110010111000100101000000111101010010110100111110101001111101010100000001010101010100111100110111000100111110000110100110 1011001110100101011110110111101101110111110100101010001101011001010000111110011010100110000100100111110101001010000110010110100111100000001110000001011010010111101011000110110111101001110001101110100010110110110010100101001011100011101011000001101111001010011001001101110011101001011000011110100101100111010111110010000111000010111011101011011110101101100111011111100000100100001000111011000011111011 1011000011011000110110101001000001101101000000010011101100000111011000110000011000100110000011010011011111111000011001011001010001101010111101101001100010001111100001101110001000011011011110011011011010111101000111001010100000001011011010110110011000010101011011010111110011011110110011111010011010001011111100110011111000110000100011110101111101010110000110101011110000111110101100110101110101000011 1110111011000001001000010100101000001101010011001110010110110111001100010110010011010010101011111101000000110001110011011110110100110001101111001011001010111110100100010101111111110110100001100011001001111001011100011011001100001010111100110100110100001001110111101110010100011101011010110110110010100101111001110111010101011111011000110110111001111010111111011101000011011101111111101100000111011111 1100001111000010000010110010100101010000011011000010011100101011011001111100010111111101010100000110110100110111000100011000110110000011111100100111101011100011001110100000001111010101000100111111001010100000010111100101010111111101010110010011100000100011101110011100010101101011110011000010000110101110111010101111010011001011101111110101100001111000001111111111110110110011000001101001010001101001 0011100100100100000001111111100101001000110001011000110110101001011100110110111101111011110100111010001011111110111011111001001111011100111101101011011000101001101010110100010010110010011100111111010010010110111100011001111111110110100111000001101010100110111100001000101100001101001000000010110110101110111001111101010110000011010001100111110101100000110111110110011111100101011110100110001111011101 1010010100101000100010011100011111001111100001010101011111101111011110111111010111000101011000000001010111110110000110001010111110001010000110010101100100010101011000000011111001101100101100101001011010000101001001001010001101111101100011000101111101000001101000100011001001111001010100101000110111111101001101001100000011101100010111000111011011100011001010111111111100000101110001101001010010100011 0000010001001101110110100100001100101011011011001110000001100101000000010101110110110111000111111111101111010111001101101100111000010010011011011010101101011001110111110000011011010111000100111111010111110010010111001010011010010100010101101111011110011011011000110001111000001111000101001110000010010101011011110110101000111101000110100001011111010110111110100000110001101000001110110011111101011111 1111000111001110100110101011010000000100110010000110101000001101000011011111001001111101000110010110111101110000101000010000011100000111100111001110011100000110001101000010001010000110110000111001110110010000001010110010010100010010110000100000010011011010000011011111101011111010000100100100111110100010101100101101101010110011111110011111111100000111110011010100100100001001111110101010000101000111 0111111110100110100100110000011101001111010101011010001010111101010010100000011000111111101110110101110100110010001001100101100101111110110110010000100110000010101110101111110000011110001110011110010111000110110101000010010100100001111000011110100011111111100110000110010001000011010001010011011000100011001011001101000010010101010000000000100000101110111101110000100111001000011101010000000100111100 1000101000011100011000101110000001000101001000101000100100000101101011001101010111111001110111101010101011011000101101111001000111011010010111000111011001001111101010111101100100010000111010101100011000001101110100100100110001010101000001111000111100001110110001011011101011011010101000011001001000000110000100011000100001101101111110101100000011000001011010100110101100100000001110110011010100000110 0100001011011001101001000011010101110000011101101011010101100001001010000100011111100110011000110010001010100001110111110111111000011110001001001100111110101111010100001110001101101001101101011011001110000100010001011001101001001111110010010100010001111011010111011101000011100010101111111111100011001101010100000100011001111011000110101101100011001000001010010001000010101100110011000110001110101110 0101100110001000010011100001110101101011011010010101011000111000000011111111000000111000100100000010110001011101101101011101101001100000100100000010001011000010000101111011011101101101111001110001110000101001010111001100011011110111000110000010110101100010001000111111101101011110110101100101000000011010100110000111001110001100100110011001111110011101010000111011110010010000110011001100001100000000 0001010010110101101101110000011011011011001101001100110011000011001011011000010110100000000011100101000110101010010011101101011011100011010001100100101101010110111000111101101111011001101000100010011001100011001001010100110011110111111100110111100001001110101000111100101000011010011100011111001010010001000000001010101011101010000001101101110001010010010101101111100110110011111010001010111101110101 1010000000010001110011001110111000111101011010110100000011101100000001100000100001111111010101100111110010000110101000010100011100101110101001110000001001011111110001111010110100011011010011111001111011010101100011101001100011101010101011011011111111011101100111101100011001011011010101101101011011100000101111011011001011110011110101001100110011110101101100111011010110111010001001000000010111000101 0011101111110100000101011111011000100110001101110011110110000111111101000100001000101111110010101100001101110011110111111110111100111100110110110011000101110100011111100010110110001000011101101111010001101000100001011011001001100110110011010111101010011011110110000111101001011000110000011010011110010011000100101111001100011100001011111010110110100000111111100000111000000111000011011000111100001000 1011111001000001110001100001110011110110111001001101010101000110001101011110111001000001000001110011001100101100000011101110111110101000100011110011000101010101111011101011110101010100100110110000110011000000001111000110001110110110000011101110111011101000010000101000010001101101001011110000011101001011101110000111011010110110111100111101100111010010110111101101110100010001111000000111001101001100 1010100011101110100011011100110011111101110010010000100111000000100001111100010011100011101101011001000110011010100011010000110011100001100011001000011001101100001110011011110011010011101111100010010110111001001011101001011110101100100000101111100010101011100111111000011010101100101001000001110010101010001010101010111001010011011010101100111000111010111101010101111100010101110001100011101100111001 1001111101111100011011011010101011110110000000101100010111001101101100001110111011101100100100010111100110001101010010110100011111001001011110110111100101011000100110110000110001101010101101101101010100001100111000100101101111101110010011011011000101001100111110000011100101100110011011010010000000000100001011010010101010111100101010100001011011010111111110010001001011110100011110000011110110000001 0000100010101100101100110111100010111100111100011111011001111101111110100011110100001000000111100001100101001000011110110111010100011111101110001000110000101110001111100100010110100001110001101110001010111100110101111101100001110010101100110001101111110110001101101101000001001010010101101011101110011000111100111010010111101000010110010110000011110010101001001010110000001001101011100111001110001101
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

© 2026 ajinori